/*
#Copyright (c) 2013, Philippe Bordron <philippe.bordron@gmail.com>
#
# This file is part of SIPPER.
#
# DCC is free software: you can redistribute it and/or modify
# it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU LESSER GENERAL PUBLIC LICENSE for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# along with SIPPER.  If not, see <http://www.gnu.org/licenses/>
*/
package combi.wip.sipper.io.dot;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jgrapht.ext.IntegerNameProvider;
import org.jgrapht.graph.DefaultDirectedWeightedGraph;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DefaultWeightedEdge;

import combi.utils.Couple;

public class AfficheGraph {


	private static String pathPrefix = "./eco00910_shuffle_meta/";
	//private static String pathPrefix = "./eco00010/";
	private static String fileGraph = pathPrefix + "modele.txt";
	static String associationsFile = pathPrefix + "associations.txt";
	private static String fileOut = pathPrefix + "modele.dot";
	

	public static void main(String[] args) {

	//chargement du graph

		DefaultDirectedWeightedGraph<Integer, DefaultWeightedEdge>graph = new DefaultDirectedWeightedGraph<Integer, DefaultWeightedEdge>(DefaultWeightedEdge.class);
		
		try {
			loadGraph(graph,fileGraph);
			//System.err.println(graph);
			
			// chargement des equivalences de notation
			Map<Integer, Couple<Couple<String,String>,String>> equivalence = loadBijection(associationsFile);
			Map<Integer, String> labelsVertices = new HashMap<Integer, String>();
			Map<DefaultWeightedEdge, Set<Integer>> labelsEdges = new HashMap<DefaultWeightedEdge, Set<Integer>>();
			for (Entry<Integer, Couple<Couple<String, String>, String>> entry : equivalence.entrySet())
			{
				labelsVertices.put(entry.getKey(),"\""+entry.getValue().getFirst().getFirst().toString() + "\\n"+ entry.getValue().getSecond().toString()+"\"");				
			}
			for (DefaultWeightedEdge e : graph.edgeSet())
			{
				Set<Integer> label = new HashSet<Integer>();
				//System.out.println(Math.round(graph.getEdgeWeight(e)));
				label.add((int)Math.round(graph.getEdgeWeight(e)));
				labelsEdges.put(e,label);
			}
			
			Map<DefaultWeightedEdge, String> edgeColor = new HashMap<DefaultWeightedEdge, String>();
			DOTColorExporter<Integer, DefaultWeightedEdge> graphDOT = new DOTColorExporter<Integer, DefaultWeightedEdge>(new IntegerNameProvider<Integer>(), new VertexAlternateNameProvider<Integer>(labelsVertices),new DOTColorEdgeNameProvider<DefaultWeightedEdge>(edgeColor , labelsEdges));

			//export au format DOT
			
			graphDOT.export(new BufferedWriter(new FileWriter(fileOut)), graph);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	private static Map<Integer, Couple<Couple<String,String>,String>>loadBijection(String fileIn) throws IOException
	{
		Map<Integer, Couple<Couple<String,String>,String>> result = new HashMap<Integer, Couple<Couple<String,String>,String>>();
		BufferedReader in = new BufferedReader (new FileReader (fileIn));
		Matcher m;
		String recoGene = "(?:" + "([^:]+):(.+)" + ")";
		String recoReaction = "(?:" + "(R[0-9]{5})" + ")";
		Pattern reco = Pattern.compile("(?:" + "([0-9]+)" + "\t\\(" + recoGene + "," + recoReaction + "\\)" + ")");
		//Pattern reco = Pattern.compile("(?:" + "([0-9]+)" + "\t\\(" + "(.+)" + ":" + "(.+)" + "\\)" +")");

		String ch;
		while ((ch = in.readLine()) != null)
		{
			try
			{
				m = reco.matcher(ch);
				while (m.find())
				{
					//result.put(Integer.valueOf(m.group(1)), new Couple<Couple<String,String>, String>(new Couple<String,String>(m.group(2), ""),m.group(3)));
					result.put(Integer.valueOf(m.group(1)), new Couple<Couple<String,String>, String>(new Couple<String,String>(m.group(2), m.group(3)),m.group(4)));
				}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
		in.close();
		return result;
	}
	
	private static void loadGraph(DefaultDirectedWeightedGraph<Integer, DefaultWeightedEdge> g, String fileIn) throws IOException
	{
		BufferedReader in;
		in = new BufferedReader (new FileReader (fileIn));
		// ajout sommets
		String ch = in.readLine();
		Integer number = Integer.valueOf(ch);
		//System.out.println(number);
		for (int i=0; i<number;i++)
		{
			g.addVertex((Integer)i);
			//Set<Integer> s = new HashSet<Integer>();
			//s.add(i);
			//regroup.put(i, s);
		}

		//ajout arcs
		Matcher m;
		String tag = "(?:([0-9]+)\\s+([0-9]+)\\s+((?:[0-9]+(?:\\.[0-9]+)?)))";
		Pattern reco = Pattern.compile(tag);
		int j = 0;
		while ((ch = in.readLine()) != null)
		{
			try
			{
				m = reco.matcher(ch);
				while (m.find())
				{
					Integer src = Integer.valueOf(m.group(1));
					Integer dest = Integer.valueOf(m.group(2));
					Double poids = Double.valueOf(m.group(3));
					g.addEdge(src, dest);
					g.setEdgeWeight(g.getEdge(src, dest), poids);
					j++;
				}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
		in.close();
	}

}
